package com.base.service.impl;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;

import javax.jws.WebService;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import com.base.enums.ResultStatus;
import com.base.model.product.ProductCcieDataItem;
import com.base.model.product.ProductData;
import com.base.model.product.ProductDataItem;
import com.base.model.product.ProductDataItemResult;
import com.base.model.product.ProductDto;
import com.base.model.product.ProductGoldDataItem;
import com.base.model.product.ProductSaleDataItem;
import com.base.model.product.ProductSettleAccountDataItem;
import com.base.model.product.ProductStoneDataItem;
import com.base.service.ProductService;
import com.base.service.business.ProductDataBusiness;
import com.base.service.business.ProductDataService;

import lombok.extern.slf4j.Slf4j;

/**
 * 单品主数据
 * @ClassName: IProductDataImpl
 * @Description: 
 * @Author xuyou
 * @DateTime 2019年11月25日 上午10:31:18
 */
@WebService(targetNamespace = "http://office.lifecycle.cn:9001/b2b/ws",
	serviceName = "ProductServiceImpl",
	portName = "productPortName",
	endpointInterface = "com.base.service.ProductService")
@Service
@Slf4j
public class ProductServiceImpl implements ProductService{

	@Autowired
	private ProductDataService productDataService;

	@Override
	public List<ProductDataItemResult> pushProductData(ProductData productData) {
		log.info("单品主数据同步数量:{}",
				CollectionUtils.isEmpty(productData.getProductDataItem()) ? 0 : productData.getProductDataItem().size());
		List<ProductDataItemResult> resultList=new ArrayList<ProductDataItemResult>();
		if (productData == null || CollectionUtils.isEmpty(productData.getProductDataItem())) {
			log.warn("未获取到数据");
			ProductDataItemResult result = new ProductDataItemResult();
			result.setZSUCCESS(ResultStatus.E.getValue());
			result.setZMESSAGE("未获取到数据");
			resultList.add(result);
			return resultList;
		}
		//获取单品信息数据
		List<ProductDataItem> productList=productData.getProductDataItem();		
		//组装数据
		List<ProductDto> dtoList = new ArrayList<ProductDto>(productList.size());
		long bengin = System.currentTimeMillis();
		for (ProductDataItem item : productList) {
			ProductDto dto = new ProductDto();
			//批次号
			String charg = item.getCHARG();
			//主数据
			dto.setProductDataItem(item);
			//金料
			dto.setProductGoldDataItem(this.getGoldDatas(charg, productData.getProductGoldDataItem()));
			//证书
			dto.setProductCcieDataItem(this.getCcieDatas(charg, productData.getProductCcieDataItem()));
			//销售
			dto.setProductSaleDataItem(this.getSaleDatas(charg, productData.getProductSaleDataItem()));
			//石料
			dto.setProductStoneDataItem(this.getStoneDatas(charg, productData.getProductStoneDataItem()));
			//意向
			dto.setProductSettleAccountDataItem(this.getSettleAccountDatas(charg, productData.getProductSettleAccountDataItem()));
			dtoList.add(dto);
			
			ProductDto dto2 = new ProductDto();
			ProductDataItem item2 = new ProductDataItem();
			item2.setCHARG("2");
			dto2.setProductDataItem(item2);
			dtoList.add(dto2);
			
			ProductDto dto3 = new ProductDto();
			ProductDataItem item3 = new ProductDataItem();
			item3.setCHARG("3");
			dto3.setProductDataItem(item3);
			dtoList.add(dto3);
		}
		
		log.info("组装数据花费时间:{}毫秒",System.currentTimeMillis()-bengin);
		
		//存放task的list
		List<FutureTask<List<ProductDataItemResult>>> futureTasks  = new ArrayList<FutureTask<List<ProductDataItemResult>>>();
		//创建一个线程池
		ExecutorService executorService = Executors.newCachedThreadPool();
		
		if (!CollectionUtils.isEmpty(dtoList)) {
			List<List<ProductDto>> splitList = this.splitList(dtoList, 1);
			for (List<ProductDto> list : splitList) {
				ProductDataBusiness business = new ProductDataBusiness();
				business.setProductDataService(productDataService);
				business.setDtoList(list);
				FutureTask<List<ProductDataItemResult>> futureTask = new FutureTask<>(business);
				futureTasks.add(futureTask);
				executorService.submit(futureTask);
			}
		}
		for (FutureTask<List<ProductDataItemResult>> task : futureTasks) {
			try {
				List<ProductDataItemResult> list = task.get();
				if (!CollectionUtils.isEmpty(list)) {
					resultList.addAll(list);
				}
			} catch (InterruptedException | ExecutionException e) {
				log.error("单品数据出现异常",e);
			}
		}
		
		//关闭线程池
		executorService.shutdown();
		
		String zsuccess = ResultStatus.S.getValue();
		String zmessage = "推送数据数量:" + productData.getProductDataItem().size() + ",返回数量:"+resultList.size() ;
		for (ProductDataItemResult result : resultList) {
			if (ResultStatus.E.getValue().equals(result.getZSUCCESS())) {
				zsuccess = ResultStatus.E.getValue();
				zmessage = zmessage +  "___" + result.getZMESSAGE() ;
				break; 
			}
		}
		// 添加日志信息
		return resultList;
	}	
	
	
	/**
	 * 获取单品金料数据
	 */
	private List<ProductGoldDataItem> getGoldDatas(String charg,List<ProductGoldDataItem> list){
		List<ProductGoldDataItem> result = new ArrayList<ProductGoldDataItem>();
		if (!CollectionUtils.isEmpty(list)) {
			for (ProductGoldDataItem item : list) {
				if (StringUtils.isNotBlank(item.getCHARG()) && 
					charg.equals(item.getCHARG())) {
					result.add(item);
				}
			}
		}
		return result;
	}
	
	/**
	 * 获取单品石料数据
	 */
	private List<ProductStoneDataItem> getStoneDatas(String charg,List<ProductStoneDataItem> list){
		List<ProductStoneDataItem> result = new ArrayList<ProductStoneDataItem>();
		if (!CollectionUtils.isEmpty(list)) {
			for (ProductStoneDataItem item : list) {
				if (StringUtils.isNotBlank(item.getCHARG()) && 
					charg.equals(item.getCHARG())) {
					result.add(item);
				}
			}
		}
		return result;
	}
	
	/**
	 * 获取单品证书数据
	 */
	private List<ProductCcieDataItem> getCcieDatas(String charg,List<ProductCcieDataItem> list){
		List<ProductCcieDataItem> result = new ArrayList<ProductCcieDataItem>();
		if (!CollectionUtils.isEmpty(list)) {
			for (ProductCcieDataItem item : list) {
				if (StringUtils.isNotBlank(item.getCHARG()) && 
						charg.equals(item.getCHARG())) {
					result.add(item);
				}
			}
		}
		return result;
	}
	
	/**
	 * 获取单品销售数据
	 */
	private List<ProductSaleDataItem> getSaleDatas(String charg,List<ProductSaleDataItem> list){
		List<ProductSaleDataItem> result = new ArrayList<ProductSaleDataItem>();
		if (!CollectionUtils.isEmpty(list)) {
			for (ProductSaleDataItem item : list) {
				if (StringUtils.isNotBlank(item.getCHARG()) && 
						charg.equals(item.getCHARG())) {
					result.add(item);
				}
			}
			list.removeAll(result);
		}
		return result;
	}
	/**
	 * 获取单品代销数据
	 */
	private List<ProductSettleAccountDataItem> getSettleAccountDatas(String charg,List<ProductSettleAccountDataItem> list){
		List<ProductSettleAccountDataItem> result = new ArrayList<ProductSettleAccountDataItem>();
		if (!CollectionUtils.isEmpty(list)) {
			for (ProductSettleAccountDataItem item : list) {
				if (StringUtils.isNotBlank(item.getCHARG()) && 
						charg.equals(item.getCHARG())) {
					result.add(item);
				}
			}
			list.removeAll(result);
		}
		return result;
	}
	
	
	/**
	   * 将源List按照指定元素数量拆分为多个List
	   *
	   * @param list 源List
	   * @param len 每个List中元素数量
	   * @return
	   */
	  private <T> List<List<T>> splitList(List<T> list, int len) {
		  long begin = System.currentTimeMillis();
	      if (list == null || list.isEmpty() || len < 1) {
	          return Collections.emptyList();
	      }
	      List<List<T>> result = new ArrayList<>();
	      int size = list.size();
	      int count = (size + len - 1) / len;
	      for (int i = 0; i < count; i++) {
	          List<T> subList = list.subList(i * len, ((i + 1) * len > size ? size : len * (i + 1)));
	          result.add(subList);
	      }
	      log.info("分割list花费时间:{}毫秒",System.currentTimeMillis() - begin);
	      return result;
	  }


	
	
}
